#include "ast.h"



past newAstNode()// 声明新的AST节点
{
	past node = malloc(sizeof(ast));
	if (node == NULL)
	{
		printf("run out of memory.\n");
		exit(0);
	}
	memset(node, 0, sizeof(ast));
	return node;
}

past newNum(int value)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)tok_INTEGER;
	var->Ast_union.ivalue = value;
	return var;
}
void showNum(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : %d\n", "Num", node->Ast_union.ivalue);
}

past newString(char *ID)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)tok_ID;
	ID = putInNameSpace(ID);
	var->Ast_union.IDentifier = ID;
	return var;
}

void showString(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : %s\n", "String", node->Ast_union.IDentifier);
}

past newCompUnit(past left, past right)
{

	left->Ast_union.node.next = right;
	return left;
}

past newConstDecl(int oper1, int oper2, past left, past right)
{

	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)ConstDecl;
	var->Ast_union.node.t_Token1 = oper1;
	var->Ast_union.node.t_Token2 = oper2;
	var->Ast_union.node.left = left;
	var->Ast_union.node.middle = NULL;
	var->Ast_union.node.right = NULL;
	var->Ast_union.node.next = NULL;
	var->Ast_union.node.left->Ast_union.node.next = right;
	return var;
}

void showConstDecl(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "ConstDecl");
	showToken(node->Ast_union.node.t_Token1);
	showToken(node->Ast_union.node.t_Token2);
	// printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);
	// showAst(node->Ast_union.node.right, nest+1);
	showAst(node->Ast_union.node.next, nest);
}

past newConstDefs(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newConstDef(int oper, past left, past middle, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)ConstDef;
	var->Ast_union.node.t_Token1 = oper;
	var->Ast_union.node.left = left;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.right = right;
	var->Ast_union.node.next = NULL;
	return var;
}

void showConstDef(past node, int nest)
{
	/*
	int i = 0;
	for(i = 0; i < nest; i ++)
		printf("  ");
	*/
	// printf("%s : ", "ConstDef");
	showToken(node->Ast_union.node.t_Token1);
	printf("\n");
	showAst(node->Ast_union.node.left, nest);
	showAst(node->Ast_union.node.middle, nest);
	showAst(node->Ast_union.node.right, nest);
	showAst(node->Ast_union.node.next, nest);
}

past newConstExps(past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)ConstExps;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = NULL;
	var->Ast_union.node.middle = NULL;
	var->Ast_union.node.next = right;

	return var;
}

void showConstExps(past node, int nest)
{

	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : [ ]\n", "ConstExps");
	showAst(node->Ast_union.node.left, nest + 1);
	// showAst(node->Ast_union.node.right, nest+1);
	showAst(node->Ast_union.node.next, nest);
}

past newConstInitVal(past left, past middle, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)ConstInitVal;
	// var->Ast_union.ConstInitVal.t_Token = oper;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = NULL;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.next = NULL;
	if (middle != NULL)
	{
		var->Ast_union.node.middle->Ast_union.node.next = right;
	}
	return var;
}

void showConstInitVal(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : \n", "ConstInitVal");
	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.middle, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

past newConstInitVals(past left, past right)
{

	left->Ast_union.node.next = right;
	return left;
}

past newVarDecl(int oper, past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)VarDecl;
	var->Ast_union.node.t_Token1 = oper;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = NULL;
	var->Ast_union.node.middle = NULL;
	var->Ast_union.node.next = NULL;
	var->Ast_union.node.left->Ast_union.node.next = right;

	return var;
}

void showVarDecl(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "VarDecl");
	showToken(node->Ast_union.node.t_Token1);
	printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);
	// showAst(node->Ast_union.node.right, nest+1);

	showAst(node->Ast_union.node.next, nest);
}

past newVarDecls(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newVarDef(int oper, past left, past middle, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)VarDef;
	var->Ast_union.node.t_Token1 = oper;
	var->Ast_union.node.left = left;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.right = right;

	return var;
}

void showVarDef(past node, int nest)
{

	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");

	printf("%s : ", "VarDef");
	if (node->Ast_union.node.t_Token1 != -1)
	{
		showToken(node->Ast_union.node.t_Token1);
	}
	printf("\n");

	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.middle, nest + 1);
	showAst(node->Ast_union.node.right, nest + 1);

	showAst(node->Ast_union.node.next, nest);
}

past newInitVal(past left, past middle, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)InitVal;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = NULL;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.next = NULL;
	if (middle != NULL)
	{
		var->Ast_union.node.middle->Ast_union.node.next = right;
	}
	return var;
}

void showInitVal(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : \n", "InitVal");

	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.middle, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

past newInitVals(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newFuncDef(int oper, past left, past middle, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)FuncDef;
	var->Ast_union.node.t_Token1 = oper;
	var->Ast_union.node.left = left;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.right = right;
	return var;
}

void showFuncDef(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "FuncDef");
	showToken(node->Ast_union.node.t_Token1);
	// printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.middle, nest + 1);
	showAst(node->Ast_union.node.right, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

past newFuncFParams(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newFuncFParamss(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newFuncFParam(int oper1, int oper2, past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)FuncFParam;
	var->Ast_union.node.left = left;
	var->Ast_union.node.t_Token1 = oper1;
	var->Ast_union.node.t_Token2 = oper2;
	var->Ast_union.node.right = right;
	return var;
}

void showFuncFParam(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "FuncFParam");
	showToken(node->Ast_union.node.t_Token1);
	if (node->Ast_union.node.t_Token2 != -1)
	{
		printf("[ ]");
	}

	printf("\n");

	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.right, nest + 1);

	showAst(node->Ast_union.node.next, nest);
}

past newBlock(past middle)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)Block;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.left = NULL;
	var->Ast_union.node.right = NULL;
	var->Ast_union.node.next = NULL;
	// var->Ast_union.node.next = NULL;
	// var->Ast_union.node.last = var;
	return var;
}

void showBlock(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : \n", "Block");

	showAst(node->Ast_union.node.middle, nest + 1);
	// showAst(node->Ast_union.node.next, nest);
}

past newBlockItems(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newStmt(int t_Token1, int t_Token2, past left, past middle, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)Stmt;
	var->Ast_union.node.t_Token1 = t_Token1;
	var->Ast_union.node.t_Token2 = t_Token2;
	var->Ast_union.node.left = left;
	var->Ast_union.node.middle = middle;
	var->Ast_union.node.right = right;
	var->Ast_union.node.next = NULL;
	// var->Ast_union.node.last = var;
	return var;
}

void showStmt(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "Stmt");

	showToken(node->Ast_union.node.t_Token1);

	showToken(node->Ast_union.node.t_Token2);

	printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.middle, nest + 1);
	showAst(node->Ast_union.node.right, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

past newLVal(past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)LVal;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = right;
	return var;
}

void showLVal(past node, int nest)
{
	showAst(node->Ast_union.node.left, nest);
	showAst(node->Ast_union.node.right, nest);
	showAst(node->Ast_union.node.next, nest);
}

past newExps(past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)Exps;
	var->Ast_union.node.left = left;
	var->Ast_union.node.next = right;
	return var;
}

void showExps(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : [ ]\n", "Exps");
	// printf("%s : \n", "Exps");
	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

past newNumber(past middle)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)Number;
	var->Ast_union.node.middle = middle;
	return var;
}

void showNumber(past node, int nest)
{

	// printf("%s : \n", "Number");
	showAst(node->Ast_union.node.middle, nest);
	showAst(node->Ast_union.node.next, nest);
}

past newUnaryExp(int t_Token, past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)UnaryExp;
	var->Ast_union.node.t_Token1 = t_Token;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = right;
	var->Ast_union.node.middle = NULL;
	var->Ast_union.node.next = NULL;
	// var->Ast_union.node.last = var;
	return var;
}

void showUnaryExp(past node, int nest)
{

	if (node->Ast_union.node.t_Token1 == -1)
	{
		showAst(node->Ast_union.node.left, nest + 1);
		showAst(node->Ast_union.node.right, nest + 1);
		return;
	}
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "UnaryExp");

	showToken(node->Ast_union.node.t_Token1);
	printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.right, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

past newFuncRParams(past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)FuncRParams;

	var->Ast_union.node.left = left;
	var->Ast_union.node.next = right;

	return var;
}

void showFuncRParams(past node, int nest)
{

	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "FuncRParams");
	printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);

	showAst(node->Ast_union.node.next, nest);
}

past newExpss(past left, past right)
{
	left->Ast_union.node.next = right;
	return left;
}

past newExpr(int oper, past left, past right)
{
	past var = newAstNode();
	var->ast_ID = (enum Non_terminator)Expr;
	var->Ast_union.node.t_Token1 = oper;
	var->Ast_union.node.left = left;
	var->Ast_union.node.right = right;
	return var;
}

void showExpr(past node, int nest)
{
	int i = 0;
	for (i = 0; i < nest; i++)
		printf("  ");
	printf("%s : ", "Expr");
	if (node->Ast_union.node.t_Token1 != -1)
	{
		showToken(node->Ast_union.node.t_Token1);
	}
	printf("\n");
	showAst(node->Ast_union.node.left, nest + 1);
	showAst(node->Ast_union.node.right, nest + 1);
	showAst(node->Ast_union.node.next, nest);
}

void showAst(past node, int nest)
{
	if (node == NULL)
		return;
	switch (node->ast_ID)
	{
	case tok_ID:
		showString(node, nest);
		break;
	case tok_INTEGER:
		showNum(node, nest);
		break;

	case 293:
		showConstDecl(node, nest);
		break;

	case 296:
		showConstDef(node, nest);
		break;
	case 297:
		showConstExps(node, nest);
		break;
	case 298:
		showConstInitVal(node, nest);
		break;

	case 300:
		showVarDecl(node, nest);
		break;

	case 302:
		showVarDef(node, nest);
		break;
	case 303:
		showInitVal(node, nest);
		break;

	case 305:
		showFuncDef(node, nest);
		break;

	case 309:
		showFuncFParam(node, nest);
		break;
	case 310:
		showBlock(node, nest);
		break;

	case 313:
		showStmt(node, nest);
		break;
	case 316:
		showLVal(node, nest);
		break;
	case 317:
		showExps(node, nest);
		break;

	case 319:
		showNumber(node, nest);
		break;
	case 320:
		showUnaryExp(node, nest);
		break;
	case 321:
		showFuncRParams(node, nest);
		break;
	case 323:
		showExpr(node, nest);
		break;
	default:
		break;
	}
}

void showToken(int Token)
{
	switch (Token)
	{
	case tok_ID:
		printf("%s", "ID");
		break; // 标识符
	case tok_INTEGER:
		printf("%s", "INTEGER");
		break; // 整数
	case tok_INT:
		printf("%s", "INT");
		break; // int
	case tok_VOID:
		printf("%s", "VOID");
		break; // void
	case tok_CONST:
		printf("%s", "CONST");
		break; // const
	case tok_IF:
		printf("%s", "IF");
		break; // if
	case tok_ELSE:
		printf("%s", "ELSE");
		break; // else
	case tok_WHILE:
		printf("%s", "WHILE");
		break; // while
	case tok_BREAK:
		printf("%s", "BREAK");
		break; // break
	case tok_CONTINUE:
		printf("%s", "CONTINUE");
		break; // continue
	case tok_RETURN:
		printf("%s", "RETURN");
		break; // return
	case tok_ADD:
		printf("%c", '+');
		break; // +
	case tok_SUB:
		printf("%c", '-');
		break; // -
	case tok_MUL:
		printf("%c", '*');
		break; // *
	case tok_DIV:
		printf("%c", '/');
		break; // /
	case tok_MODULO:
		printf("%c", '%');
		break; // %
	case tok_LESS:
		printf("%c", '<');
		break; // <
	case tok_LESSEQ:
		printf("%s", "<=");
		break; // <=
	case tok_GREAT:
		printf("%c", '>');
		break; // >
	case tok_GREATEQ:
		printf("%s", ">=");
		break; // >=
	case tok_NOTEQ:
		printf("%s", "!=");
		break; // !=
	case tok_EQ:
		printf("%s", "==");
		break; // ==
	case tok_NOT:
		printf("%c", '!');
		break; // !
	case tok_AND:
		printf("%s", "&&");
		break; // &&
	case tok_OR:
		printf("%s", "||");
		break; // ||
	case tok_ASSIGN:
		printf("%c", '=');
		break; // =

	default:
		break;
	}
}

char * NameSpace[1024];
int Name_Num = 0;
char * putInNameSpace(char *ID)
{
	size_t i,flag = 0;
	for (i = 0; i < Name_Num; i++)
	{
		size_t j;
		for (j = 0;'\0' != *(NameSpace[i]+j) && '\0' != ID[j]; j++)
        {
            if (ID[j] == *(NameSpace[i]+j))
            {
                flag = 1;
            }
            else
            {
                flag = 0;
            }
            if (0 == flag)
            {
                break;
            }
        }
        if (1 == flag && '\0' == ID[j])
        {
            break;
        }
		else
		{
			flag = 0;
		}
    }
	if (flag)
    {
        return NameSpace[i];
    }
    
	if (1024 != Name_Num)
	{
		NameSpace[Name_Num] = &ID[0];
        Name_Num++;
		return &ID[0];
	}
	
}
